package com.zs.grain.ui

import android.app.Application
import android.media.MediaPlayer
import android.media.MediaPlayer.MEDIA_ERROR_UNKNOWN
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.lifecycle.MutableLiveData
import com.alibaba.android.arouter.launcher.ARouter
import com.jeremyliao.liveeventbus.LiveEventBus
import com.xnkj1688.semplibrary.mvvm.*
import com.xnkj1688.semplibrary.entity.*
import com.xnkj1688.semplibrary.ulti.DateUtil
import com.zs.grain.*
import com.zs.grain.service.*
import com.zslibrary.BusMaster.BusMaster
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.SingleSubject
import java.io.File
import java.lang.Exception
import java.text.SimpleDateFormat
import java.util.*

import javax.inject.Inject
import kotlin.concurrent.schedule

/**
 * Created by Wesley on 2017/7/29.
 */

class MainViewModel @Inject constructor(
    val mApp: Application,
    val mDataService: DataService,
    val mDeviceService: DeviceService
) : BaseViewModel(mApp) {

    val logo = MutableLiveData<String>()
    val title = MutableLiveData<String>()
    val qr = MutableLiveData<String>()
    val isOnline = MutableLiveData<Boolean>()
    val isReady = MutableLiveData<Boolean>()
    val time = MutableLiveData<String>()
    val downCount = MutableLiveData<Int>()
    var order: Order = Order()
        private set

    var menuNo: Int? = null
        private set

    private var mTimeTimer: Timer? = null
    private var mDisposable: Disposable? = null

    init {
//        logo.value = "file://${mDataService.logosPath}/${mDataService.logo}"
        logo.value = "res://${mApp.packageName}/${R.mipmap.logo}"
        title.value = "res://${mApp.packageName}/${R.mipmap.title}"
        qr.value = "res://${mApp.packageName}/${R.mipmap.offline}"

        LiveEventBus.get("SignalR.SceneQr", String::class.java).observeStickyForever {
            isOnline.postValue(it != "")
            if (it != "") qr.postValue("res://${mApp.packageName}/${R.mipmap.online}")
            else qr.postValue("res://${mApp.packageName}/${R.mipmap.offline}")
        }
        LiveEventBus.get("DeviceService.IsReady", Boolean::class.java)
            .observeStickyForever() {
                isReady.value = it
            }

        this.startTimeTimer()

        //this.startAdsPlayTimer()
    }

    private var times = 0
    private var mAdsTimer: Timer? = null
    fun startAdsPlayTimer(){
        times = 0
        this.downCount.postValue(120)
        this.mAdsTimer = Timer()
        this.mAdsTimer?.schedule(1000,1000,{
            var count = Math.max(0, (downCount.value ?: 1) - 1)
            downCount.postValue(count)
            if (count <= 0) stopAdsTimer()
            if (count % 30 != 1) return@schedule
            times++
        })
    }

    fun stopAdsTimer() {
        this.mAdsTimer?.cancel()
        this.mAdsTimer = null

        var notify = this.getNotify("RefreshVideoViewSize")
        notify.putBoolean("fullScreen", true)
        this.uiNotify.value = notify
    }

    fun init() {
        var bundle = Bundle()
        bundle.putString("UI", "Menus")
        LiveEventBus.get("SwitchUI").post(bundle)

        LiveEventBus.get("RemotePush.refreshPlayer").observeStickyForever(){
            initDisposable()
        }
        initDisposable()
    }

    fun initDisposable(){
        mDisposable?.dispose()
        mDisposable = SingleSubject.create<Unit>() {
            try {
                Thread.sleep(1000)
                var advertisements = mDataService.advertisements
                playAdvertisements(mDisposable!!, advertisements)//播放过就不能隐藏
            } catch (e: Exception) {
                Log.e(TAG, "广告播放终止：" + e.message)
            }
        }.subscribeOn(Schedulers.io())
            .subscribe({ }, { it.printStackTrace() })
    }

    fun onClickMenu(vm: MenuViewModel) {
        if (!(vm.enable.value ?: true))
            return

        if (menuNo != null) return
        menuNo = vm.mMenu.no.toInt()
        ARouter.getInstance()
            .build(ARouterPath.DeployFragment)
            .withLong("OrderId", this.order.id)
            .withInt("MenuNo", this.menuNo ?: 0)
            .navigation()
    }

    fun onClickScanQr() {
        if (this.order.id > 0) return
        if (this.order.details.size <= 0) {
            this.showToast("没有选择商品，请先选择商品！", Toast.LENGTH_LONG)
            return
        }

        this.order.createTime = Date(System.currentTimeMillis())
        this.order.timestamp = this.order?.createTime ?: Date()
        val time = DateUtil.format(this.order?.createTime, "yyMMddHHmmss")
        this.order.id = java.lang.Long.parseLong(time) * 10000000 + mDataService.terminalId * 10
        var no = 1
        for (item in this.order.details) {
            item.id = null
            item.orderId = this.order.id
            item.no = no++
        }
        mDataService.save(this.order)
        mDataService.insertLog("OrderMVM:" + mDataService.currentOrder?.id.toString())
        mDataService.currentOrder = this.order
        uiNotify.value = this.getNotify("ScanQr")
    }

    fun onClickFace() {
        if (this.order.id > 0) return
        if (this.order.details.size <= 0) {
            showToast("没有选择商品，请先选择商品！", Toast.LENGTH_LONG)
            return
        }

        this.order.createTime = Date(System.currentTimeMillis())
        this.order.timestamp = this.order?.createTime ?: Date()
        val time = DateUtil.format(this.order?.createTime, "yyMMddHHmmss")
        this.order.id = java.lang.Long.parseLong(time) * 10000000 + mDataService.terminalId * 10
        var no = 1
        for (item in this.order.details) {
            item.id = null
            item.orderId = this.order.id
            item.no = no++
        }
        mDataService.save(this.order)
        mDataService.insertLog("OrderMVM2:" + mDataService.currentOrder?.id.toString())
        mDataService.currentOrder = this.order
        uiNotify.value = this.getNotify("Face")
    }

    fun onClickCancel() {
        this.clearOrder()
    }

    fun onVideoError(mp: MediaPlayer, what: Int, extra: Int): Boolean {
        mp.stop()
        if (what == MEDIA_ERROR_UNKNOWN) {
            advertisement?.enable = false
        }
        advertisement = null
        return false
    }

    fun onVideoCompletion() {
        advertisement = null
    }

    fun startTimeTimer() {
        val sdFormatter = SimpleDateFormat("MM-dd HH:mm")
        sdFormatter.timeZone = TimeZone.getTimeZone("GMT+8")
        this.mTimeTimer?.cancel()
        this.mTimeTimer = Timer()
        this.mTimeTimer?.schedule(1000, 1000) {
            var date = Date(System.currentTimeMillis())
            time.postValue(sdFormatter.format(date))
        }
    }

    fun checkPasswordForMaintenance(password: String, auth: String): Boolean {
        if (mDataService.isEmulator || !BusMaster.getInstance(mApp).isMachineInit) {
            if (mDataService.password == password) {
                var enterable = true
                //val clocksArray:ArrayList<AlarmSignal> = LocalDataBase.getClocksArray()
                //for(ca in clocksArray) {
                if (mDeviceService.isMakingProduct) {//(ca.setting.contains("makingProduct")) {
                    showToast("产品制作中...", Toast.LENGTH_SHORT)
                    enterable = false
                }
                //}
                if (enterable) {
                    ARouter.getInstance()
                        .build(ARouterPath.MaintenanceActivity)
                        .withString("auth", auth)
                        .navigation()
                }
                return true
            } else {
                showToast("密码错误", Toast.LENGTH_LONG)
                return false
            }
        } else {
            showToast("设备初始化中...", Toast.LENGTH_SHORT)
            return false
        }
    }

    fun enterMaintenance(cardNumber: String, auth: String) {
        var enterable = true
        if (mDeviceService.isMakingProduct) {//(ca.setting.contains("makingProduct")) {
            showToast("产品制作中...", Toast.LENGTH_SHORT)
            enterable = false
        }
        if (enterable) {
            var auther = ""
            when (auth) {
                "1" -> auther = "维护人员刷卡进入OUI"
                "2" -> auther = "运维人员刷卡进入OUI"
            }
            mDataService.insertLog("Operation:" + auther + ",卡号:" + cardNumber)
            ARouter.getInstance()
                .build(ARouterPath.MaintenanceActivity)
                .withString("cardNumber", cardNumber)
                .withString("auth", auth)
                .navigation()
        }
    }

    fun clearOrder() {
        this.order = Order()
        mDataService.insertLog("OrderM:" + mDataService.currentOrder?.id.toString())
        mDataService.currentOrder = null
    }

    fun refreshPlayer(advertisements: List<Advertisement>){
        var adsPath = mDataService.adsPath
        var notify = getNotify("Advertisement")
        for (item in advertisements) {
            val file = File(adsPath + item.fileName)
            if (!file.exists() || !(item.enable ?: false)) continue
            //if (disposable.isDisposed) break

            notify.putString("FileName", file.absolutePath)//file.absolutePath真实可播的文件
            uiNotify.postValue(notify)
        }
    }

    var advertisement: Advertisement? = null
    fun playAdvertisements(disposable: Disposable, advertisements: List<Advertisement>) {
        var notify = getNotify("Advertisement")
        try {
            var adsPath = mDataService.adsPath
            while (disposable == mDisposable && !disposable.isDisposed) {
                for (item in advertisements) {
                    val file = File(adsPath + item.fileName)
                    if (!file.exists() || !(item.enable ?: false)) continue
                    if (disposable.isDisposed) break

                    notify.putString("FileName", file.absolutePath)//file.absolutePath真实可播的文件
                    uiNotify.postValue(notify)
                    if (item.duration == null) {
                        advertisement = item
                        while (advertisement != null) Thread.sleep(500)
                    } else {
                        Thread.sleep(item.duration * 1000L)
                    }
                }
                Thread.sleep(1000)
            }
        } catch (e: Exception) {
//            e.printStackTrace()
        }
    }

    fun insertLog(logContent: String) {
        mDataService.insertLog(logContent)
    }

    companion object {
        val TAG = "MainViewModel"
    }
}
